package com.itbaizhan;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/*Servlet线程安全问题*/

/*在Servlet中使用的是多线程方式来执行service()方法处理请求，
所以我们在使用Servlet时需要考虑到线程安全问题，在多线程中对于对象中的
成员变量是最不安全的，所以不要在Servlet中通过成员变量的方式来存放数据，
如果一定要使用成员变量存储数据，在对数据进行操作时需要使用线程同步的方式
来解决线程安全问题，避免出现数据张冠李戴现象。*/
/*启动tomcat后，在地址写上namewcd 值  http://localhost:8080/javaEE/threadsafe.do?name=itbz*/

/*servlet不建议定义成员变量，可以定义局部变量都定义这，成员变量的值以读取为主
* ，尽量不要修改，如果真的要修改，一定要有synchronized()*/
public class ThreadSafeServlet extends HttpServlet {
    //定义成员变量
    private PrintWriter pw;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String value =  req.getParameter("name");
//线程不安全
      /* pw=resp.getWriter();

       try{
           //线程休眠5s
           Thread.sleep(5000);
           pw.println(value);
           pw.flush();
           pw.close();
       }catch (Exception e){
           e.printStackTrace();

       }*/

       //线程同步才安全，但一般不建义定义成员变量，修改数据  将线程并行改为串行
        //this表示当前对象
        /*如果当前都是调用多个servlet方法，都是同一个类下的servlet，都会互斥，并行改为串行*/
        synchronized (this){
            pw=resp.getWriter();

            try{
                //线程休眠5s
                Thread.sleep(5000);
                pw.println(value);
                pw.flush();
                pw.close();
            }catch (Exception e){
                e.printStackTrace();

            }
        }


    }
}
